home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / GIFLIB12.ARJ / GIFTEXT.C < prev    next >
C/C++ Source or Header  |  1991-05-12  |  14KB  |  460 lines

  1. /*****************************************************************************
  2. *   "Gif-Lib" - Yet another gif library.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, Jun. 1989   *
  5. ******************************************************************************
  6. * Program to dump GIF file content as TEXT information                 *
  7. * Options:                                     *
  8. * -q : quite printing mode.                             *
  9. * -c : include the color maps as well.                         *
  10. * -e : include encoded information packed as bytes as well.             *
  11. * -z : include encoded information (12bits) codes as result from the zl alg. *
  12. * -p : dump pixel information instead of encoded information.             *
  13. * -r : same as -p but dump one pixel as one byte in binary form with no      *
  14. *      other information. This will create a file of size Width by Height.   *
  15. * -h : on line help.                                 *
  16. ******************************************************************************
  17. * History:                                     *
  18. * 28 Jun 89 - Version 1.0 by Gershon Elber.                     *
  19. * 21 Dec 89 - Fix segmentation fault problem in PrintCodeBlock (Version 1.1) *
  20. * 25 Dec 89 - Add the -r flag for raw output.                                *
  21. *****************************************************************************/
  22.  
  23. #ifdef __MSDOS__
  24. #include <stdlib.h>
  25. #include <alloc.h>
  26. #include <conio.h>
  27. #include <io.h>
  28. #endif /* __MSDOS__ */
  29.  
  30. #include <stdio.h>
  31. #include <ctype.h>
  32. #include <fcntl.h>
  33. #include "gif_lib.h"
  34. #include "getarg.h"
  35.  
  36. #define PROGRAM_NAME    "GifText"
  37.  
  38. #define MAKE_PRINTABLE(c)  (isprint(c) ? (c) : ' ')
  39.  
  40. #ifdef __MSDOS__
  41. extern unsigned int
  42.     _stklen = 16384;                 /* Increase default stack size. */
  43. #endif /* __MSDOS__ */
  44.  
  45. #ifdef SYSV
  46. static char *VersionStr =
  47.         "Gif library module,\t\tGershon Elber\n\
  48.     (C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  49. static char
  50.     *CtrlStr = "GifText q%- c%- e%- z%- p%- r%- h%- GifFile!*s";
  51. #else
  52. static char
  53.     *VersionStr =
  54.     PROGRAM_NAME
  55.     GIF_LIB_VERSION
  56.     "    Gershon Elber,    "
  57.     __DATE__ ",   " __TIME__ "\n"
  58.     "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  59. static char
  60.     *CtrlStr =
  61.     PROGRAM_NAME
  62.     " q%- c%- e%- z%- p%- r%- h%- GifFile!*s";
  63. #endif /* SYSV */
  64.  
  65. static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, int Reset);
  66. static void PrintPixelBlock(GifByteType *PixelBlock, int Len, int Reset);
  67. static void PrintExtBlock(GifByteType *Extension, int Reset);
  68. static void PrintLZCodes(GifFileType *GifFile);
  69.  
  70. /******************************************************************************
  71. * Interpret the command line and scan the given GIF file.              *
  72. ******************************************************************************/
  73. void main(int argc, char **argv)
  74. {
  75.     int i, j, ExtCode, CodeSize, Error, NumFiles, Len,
  76.     ColorMapFlag = FALSE, EncodedFlag = FALSE, LZCodesFlag = FALSE,
  77.     PixelFlag = FALSE, HelpFlag = FALSE, RawFlag = FALSE, ImageNum = 1;
  78.     char *GifFileName, **FileName = NULL;
  79.     GifPixelType *Line;
  80.     GifRecordType RecordType;
  81.     GifByteType *CodeBlock, *Extension;
  82.     GifFileType *GifFile;
  83.  
  84.     if ((Error = GAGetArgs(argc, argv, CtrlStr,
  85.         &GifQuitePrint, &ColorMapFlag, &EncodedFlag,
  86.         &LZCodesFlag, &PixelFlag, &RawFlag, &HelpFlag,
  87.         &NumFiles, &FileName)) != FALSE ||
  88.     (NumFiles > 1 && !HelpFlag)) {
  89.     if (Error)
  90.         GAPrintErrMsg(Error);
  91.     else if (NumFiles > 1)
  92.         GIF_MESSAGE("Error in command line parsing - one GIF file please.");
  93.     GAPrintHowTo(CtrlStr);
  94.     exit(1);
  95.     }
  96.  
  97.     if (HelpFlag) {
  98.     fprintf(stderr, VersionStr);
  99.     GAPrintHowTo(CtrlStr);
  100.     exit(0);
  101.     }
  102.  
  103.     if (NumFiles == 1) {
  104.     GifFileName = *FileName;
  105.     if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
  106.         PrintGifError();
  107.         exit(-1);
  108.     }
  109.     }
  110.     else {
  111.     /* Use the stdin instead: */
  112.     GifFileName = "Stdin";
  113.     if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
  114.         PrintGifError();
  115.         exit(-1);
  116.     }
  117.     }
  118.  
  119.     /* Because we write binary data - make sure no text will be written. */
  120.     if (RawFlag) {
  121.     ColorMapFlag = EncodedFlag = LZCodesFlag = PixelFlag = FALSE;
  122. #ifdef __MSDOS__
  123.     setmode(1, O_BINARY);             /* Make sure it is in binary mode. */
  124. #endif /* __MSDOS__ */
  125.     }
  126.     else {
  127.     printf("\n%s:\n\n\tScreen Size - Width = %d, Height = %d.\n",
  128.            GifFileName, GifFile -> SWidth, GifFile -> SHeight);
  129.     printf("\tColorResolution = %d, BitsPerPixel = %d, BackGround = %d.\n",
  130.            GifFile -> SColorResolution, GifFile -> SBitsPerPixel,
  131.            GifFile -> SBackGroundColor);
  132.     if (GifFile -> SColorMap)
  133.         printf("\tHas Global Color Map.\n\n");
  134.     else
  135.         printf("\tNo Global Color Map.\n\n");
  136.     if (ColorMapFlag && GifFile -> SColorMap) {
  137.         printf("\tGlobal Color Map:\n");
  138.         Len = 1 << GifFile -> SBitsPerPixel;
  139.         for (i = 0; i < Len; i+=4) {
  140.         for (j = 0; j < 4 && j < Len; j++) {
  141.             printf("%3d: %02xh %02xh %02xh   ", i + j,
  142.                GifFile -> SColorMap[i + j].Red,
  143.                GifFile -> SColorMap[i + j].Green,
  144.                GifFile -> SColorMap[i + j].Blue);
  145.         }
  146.         printf("\n");
  147.         }
  148.     }
  149.     }
  150.  
  151.     do {
  152.     if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
  153.         PrintGifError();
  154.         exit(-1);
  155.     }
  156.     switch (RecordType) {
  157.         case IMAGE_DESC_RECORD_TYPE:
  158.         if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
  159.             PrintGifError();
  160.             exit(-1);
  161.         }
  162.         if (!RawFlag) {
  163.             printf("\nImage #%d:\n\n\tImage Size - Left = %d, Top = %d, Width = %d, Height = %d.\n",
  164.                ImageNum++, GifFile -> ILeft, GifFile -> ITop,
  165.                GifFile -> IWidth, GifFile -> IHeight);
  166.             printf("\tImage is %s",
  167.                GifFile -> IInterlace ? "Interlaced" :
  168.                             "Non Interlaced");
  169.             if (GifFile -> IColorMap != NULL)
  170.             printf(", BitsPerPixel = %d.\n",
  171.                         GifFile -> IBitsPerPixel);
  172.             else
  173.             printf(".\n");
  174.             if (GifFile -> IColorMap)
  175.             printf("\tImage Has Color Map.\n");
  176.             else
  177.             printf("\tNo Image Color Map.\n");
  178.             if (ColorMapFlag && GifFile -> IColorMap) {
  179.             Len = 1 << GifFile -> IBitsPerPixel;
  180.             for (i = 0; i < Len; i+=4) {
  181.                 for (j = 0; j < 4 && j < Len; j++) {
  182.                 printf("%3d: %02xh %02xh %02xh   ", i + j,
  183.                        GifFile -> IColorMap[i + j].Red,
  184.                        GifFile -> IColorMap[i + j].Green,
  185.                        GifFile -> IColorMap[i + j].Blue);
  186.                 }
  187.                 printf("\n");
  188.             }
  189.             }
  190.         }
  191.  
  192.         if (EncodedFlag) {
  193.             if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
  194.             PrintGifError();
  195.             exit(-1);
  196.             }
  197.             printf("\nImage LZ compressed Codes (Code Size = %d):\n",
  198.                CodeSize);
  199.             PrintCodeBlock(GifFile, CodeBlock, TRUE);
  200.             while (CodeBlock != NULL) {
  201.             if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
  202.                 PrintGifError();
  203.                 exit(-1);
  204.             }
  205.             PrintCodeBlock(GifFile, CodeBlock, FALSE);
  206.             }
  207.         }
  208.         else if (LZCodesFlag) {
  209.             PrintLZCodes(GifFile);
  210.         }
  211.         else if (PixelFlag) {
  212.             Line = (GifPixelType *) malloc(GifFile -> IWidth *
  213.                         sizeof(GifPixelType));
  214.             for (i = 0; i < GifFile -> IHeight; i++) {
  215.             if (DGifGetLine(GifFile, Line, GifFile -> IWidth)
  216.                 == GIF_ERROR) {
  217.                 PrintGifError();
  218.                 exit(-1);
  219.             }
  220.             PrintPixelBlock(Line, GifFile -> IWidth, i == 0);
  221.             }
  222.             PrintPixelBlock(NULL, GifFile -> IWidth, FALSE);
  223.             free((char *) Line);
  224.         }
  225.         else if (RawFlag) {
  226.             Line = (GifPixelType *) malloc(GifFile -> IWidth *
  227.                         sizeof(GifPixelType));
  228.             for (i = 0; i < GifFile -> IHeight; i++) {
  229.             if (DGifGetLine(GifFile, Line, GifFile -> IWidth)
  230.                 == GIF_ERROR) {
  231.                 PrintGifError();
  232.                 exit(-1);
  233.             }
  234.             fwrite(Line, 1, GifFile -> IWidth, stdout);
  235.             }
  236.             free((char *) Line);
  237.         }
  238.         else {
  239.             /* Skip the image: */
  240.             if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
  241.             PrintGifError();
  242.             exit(-1);
  243.             }
  244.             while (CodeBlock != NULL) {
  245.             if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
  246.                 PrintGifError();
  247.                 exit(-1);
  248.             }
  249.             }
  250.  
  251.         }
  252.         break;
  253.         case EXTENSION_RECORD_TYPE:
  254.         if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
  255.             PrintGifError();
  256.             exit(-1);
  257.         }
  258.         if (!RawFlag) {
  259.             printf("\nExtension Record (Ext Code = %d [%c]):\n",
  260.                ExtCode, MAKE_PRINTABLE(ExtCode));
  261.             PrintExtBlock(Extension, TRUE);
  262.         }
  263.         while (Extension != NULL) {
  264.             if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
  265.             PrintGifError();
  266.             exit(-1);
  267.             }
  268.             PrintExtBlock(Extension, FALSE);
  269.         }
  270.         break;
  271.         case TERMINATE_RECORD_TYPE:
  272.         break;
  273.         default:             /* Should be traps by DGifGetRecordType */
  274.         break;
  275.     }
  276.     }
  277.     while (RecordType != TERMINATE_RECORD_TYPE);
  278.  
  279.     if (DGifCloseFile(GifFile) == GIF_ERROR) {
  280.     PrintGifError();
  281.     exit(-1);
  282.     }
  283.  
  284.     if (!RawFlag) printf("\nGif file terminated normally.\n");
  285. }
  286.  
  287. /******************************************************************************
  288. * Print the given CodeBlock - a string in pascal notation (size in first      *
  289. * place). Save local information so printing can be performed continuously,   *
  290. * or reset to start state if Reset. If CodeBlock is NULL, output is flushed   *
  291. ******************************************************************************/
  292. static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, int Reset)
  293. {
  294.     static int CrntPlace = 0, Print = TRUE;
  295.     static long CodeCount = 0;
  296.     char c;
  297.     int i, Percent, Len;
  298.     long NumBytes;
  299.  
  300.     if (Reset || CodeBlock == NULL) {
  301.     if (CodeBlock == NULL) {
  302.         if (CrntPlace > 0) {
  303.         if (Print) printf("\n");
  304.         CodeCount += CrntPlace - 16;
  305.         }
  306.         if (GifFile -> IColorMap)
  307.         NumBytes = ((((long) GifFile -> IWidth) * GifFile -> IHeight)
  308.                 * GifFile -> IBitsPerPixel) / 8;
  309.         else
  310.         NumBytes = ((((long) GifFile -> IWidth) * GifFile -> IHeight)
  311.                 * GifFile -> SBitsPerPixel) / 8;
  312.         Percent = 100 * CodeCount / NumBytes;
  313.         printf("\nCompression ratio: %ld/%ld (%d%%).\n",
  314.             CodeCount, NumBytes, Percent);
  315.         return;
  316.     }
  317.     CrntPlace = 0;
  318.     CodeCount = 0;
  319.     Print = TRUE;
  320.     }
  321.  
  322.     Len = CodeBlock[0];
  323.     for (i = 1; i <= Len; i++) {
  324.     if (CrntPlace == 0) {
  325.         if (Print) printf("\n%05lxh:  ", CodeCount);
  326.         CodeCount += 16;
  327.     }
  328. #ifdef __MSDOS__
  329.     if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
  330. #endif /* __MSDOS__ */
  331.     if (Print) printf(" %02xh", CodeBlock[i]);
  332.     if (++CrntPlace >= 16) CrntPlace = 0;
  333.     }
  334. }
  335.  
  336. /******************************************************************************
  337. * Print the given Extension - a string in pascal notation (size in first      *
  338. * place). Save local information so printing can be performed continuously,   *
  339. * or reset to start state if Reset. If Extension is NULL, output is flushed   *
  340. ******************************************************************************/
  341. static void PrintExtBlock(GifByteType *Extension, int Reset)
  342. {
  343.     static int CrntPlace = 0, Print = TRUE;
  344.     static long ExtCount = 0;
  345.     static char HexForm[49], AsciiForm[17];
  346.     char c;
  347.     int i, Len;
  348.  
  349.     if (Reset || Extension == NULL) {
  350.     if (Extension == NULL) {
  351.         if (CrntPlace > 0) {
  352.         HexForm[CrntPlace * 3] = 0;
  353.         AsciiForm[CrntPlace] = 0;
  354.         if (Print) printf("\n%05lx: %-49s  %-17s\n",
  355.                 ExtCount, HexForm, AsciiForm);
  356.         return;
  357.         }
  358.         else if (Print)
  359.         printf("\n");
  360.     }
  361.     CrntPlace = 0;
  362.     ExtCount = 0;
  363.     Print = TRUE;
  364.     }
  365.  
  366.     if (!Print) return;
  367.  
  368.     Len = Extension[0];
  369.     for (i = 1; i <= Len; i++) {
  370.     sprintf(&HexForm[CrntPlace * 3], " %02x", Extension[i]);
  371.     sprintf(&AsciiForm[CrntPlace], "%c", MAKE_PRINTABLE(Extension[i]));
  372. #ifdef __MSDOS__
  373.     if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
  374. #endif /* __MSDOS__ */
  375.     if (++CrntPlace == 16) {
  376.         HexForm[CrntPlace * 3] = 0;
  377.         AsciiForm[CrntPlace] = 0;
  378.         if (Print) printf("\n%05lx: %-49s  %-17s",
  379.                 ExtCount, HexForm, AsciiForm);
  380.         ExtCount += 16;
  381.         CrntPlace = 0;
  382.     }
  383.     }
  384. }
  385.  
  386. /******************************************************************************
  387. * Print the given PixelBlock of length Len.                      *
  388. * Save local information so printing can be performed continuously,           *
  389. * or reset to start state if Reset. If PixelBlock is NULL, output is flushed  *
  390. ******************************************************************************/
  391. static void PrintPixelBlock(GifByteType *PixelBlock, int Len, int Reset)
  392. {
  393.     static int CrntPlace = 0, Print = TRUE;
  394.     static long ExtCount = 0;
  395.     static char HexForm[49], AsciiForm[17];
  396.     char c;
  397.     int i;
  398.  
  399.     if (Reset || PixelBlock == NULL) {
  400.     if (PixelBlock == NULL) {
  401.         if (CrntPlace > 0) {
  402.         HexForm[CrntPlace * 3] = 0;
  403.         AsciiForm[CrntPlace] = 0;
  404.         if (Print) printf("\n%05lx: %-49s  %-17s\n",
  405.                 ExtCount, HexForm, AsciiForm);
  406.         }
  407.         else if (Print)
  408.         printf("\n");
  409.     }
  410.     CrntPlace = 0;
  411.     ExtCount = 0;
  412.     Print = TRUE;
  413.     if (PixelBlock == NULL) return;
  414.     }
  415.  
  416.     if (!Print) return;
  417.  
  418.     for (i = 0; i < Len; i++) {
  419.     sprintf(&HexForm[CrntPlace * 3], " %02x", PixelBlock[i]);
  420.     sprintf(&AsciiForm[CrntPlace], "%c", MAKE_PRINTABLE(PixelBlock[i]));
  421. #ifdef __MSDOS__
  422.     if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
  423. #endif /* __MSDOS__ */
  424.     if (++CrntPlace == 16) {
  425.         HexForm[CrntPlace * 3] = 0;
  426.         AsciiForm[CrntPlace] = 0;
  427.         if (Print) printf("\n%05lx: %-49s  %-17s",
  428.                 ExtCount, HexForm, AsciiForm);
  429.         ExtCount += 16;
  430.         CrntPlace = 0;
  431.     }
  432.     }
  433. }
  434.  
  435. /******************************************************************************
  436. * Print the image as LZ codes (each 12bits), until EOF marker is reached.     *
  437. ******************************************************************************/
  438. static void PrintLZCodes(GifFileType *GifFile)
  439. {
  440.     char c;
  441.     int Code, Print = TRUE, CrntPlace = 0;
  442.     long CodeCount = 0;
  443.  
  444.     do {
  445.     if (Print && CrntPlace == 0) printf("\n%05lx:", CodeCount);
  446.     if (DGifGetLZCodes(GifFile, &Code) == GIF_ERROR) {
  447.         PrintGifError();
  448.         exit(-1);
  449.     }
  450.     if (Print && Code >= 0)
  451.         printf(" %03x", Code);          /* EOF Code is returned as -1. */
  452.     CodeCount++;
  453.     if (++CrntPlace >= 16) CrntPlace = 0;
  454. #ifdef __MSDOS__
  455.     if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
  456. #endif /* __MSDOS__ */
  457.     }
  458.     while (Code >= 0);
  459. }
  460.